home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / tiff / tif_getimage.c < prev    next >
C/C++ Source or Header  |  1995-06-21  |  28KB  |  1,161 lines

  1. /* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_getimage.c,v 1.24 1994/09/17 23:22:37 sam Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Sam Leffler
  5.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * TIFF Library
  29.  *
  30.  * Read and return a packed RGBA image.
  31.  */
  32. #include "tiffiop.h"
  33.  
  34. typedef    u_char RGBvalue;
  35.  
  36. static    uint16 bitspersample;
  37. static    uint16 samplesperpixel;
  38. static    uint16 photometric;
  39. static    uint16 orientation;
  40. static    uint16 extrasamples;
  41. static    uint16 planarconfig;
  42. /* colormap for pallete images */
  43. static    uint16 *redcmap, *greencmap, *bluecmap;
  44. static    int stoponerr;            /* stop on read error */
  45. /* YCbCr support */
  46. static    uint16 YCbCrHorizSampling;
  47. static    uint16 YCbCrVertSampling;
  48. static    float *YCbCrCoeffs;
  49. static    float *refBlackWhite;
  50.  
  51. static    uint32 **BWmap;
  52. static    uint32 **PALmap;
  53.  
  54. static    int gt(TIFF*, uint32, uint32, uint32*);
  55. static    int gtTileContig(TIFF*, uint32*, RGBvalue*, uint32, uint32);
  56. static    int gtTileSeparate(TIFF*, uint32*, RGBvalue*, uint32, uint32);
  57. static    int gtStripContig(TIFF*, uint32*, RGBvalue*, uint32, uint32);
  58. static    int gtStripSeparate(TIFF*, uint32*, RGBvalue*, uint32, uint32);
  59. static    int makebwmap(TIFF*, RGBvalue*);
  60. static    int makecmap(TIFF*, u_short*, u_short*, u_short*);
  61. static    void initYCbCrConversion(void);
  62.  
  63. int
  64. TIFFReadRGBAImage(TIFF* tif,
  65.     uint32 rwidth, uint32 rheight, uint32* raster, int stop)
  66. {
  67.     int ok, alpha;
  68.     uint32 width, height;
  69.     uint16 *sampleinfo;
  70.  
  71.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  72.     switch (bitspersample) {
  73.     case 1: case 2: case 4:
  74.     case 8: case 16:
  75.         break;
  76.     default:
  77.         TIFFError(TIFFFileName(tif),
  78.             "Sorry, can not handle %d-bit images", bitspersample);
  79.         return (0);
  80.     }
  81.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  82.     if (samplesperpixel > 4) {
  83.         TIFFError(TIFFFileName(tif),
  84.             "Sorry, can not handle images with %d-samples/pixel",
  85.             samplesperpixel);
  86.         return (0);
  87.     }
  88.     TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
  89.         &extrasamples, &sampleinfo);
  90.     alpha = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
  91.     TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  92.     switch (samplesperpixel - extrasamples) {
  93.     case 3:
  94.         break;
  95.     case 1: case 4:
  96. /* XXX */
  97.         if (!alpha || planarconfig != PLANARCONFIG_CONTIG)
  98.             break;
  99.         /* fall thru... */
  100.     default:
  101.         TIFFError(TIFFFileName(tif),
  102.             "Sorry, can not handle %d-channel %s images%s",
  103.             samplesperpixel,
  104.             planarconfig == PLANARCONFIG_CONTIG ?
  105.             "packed" : "separated",
  106.             alpha ? " with alpha" : "");
  107.         return (0);
  108.     }
  109.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  110.         switch (samplesperpixel) {
  111.         case 1:
  112.             photometric = PHOTOMETRIC_MINISBLACK;
  113.             break;
  114.         case 3: case 4:
  115.             photometric = PHOTOMETRIC_RGB;
  116.             break;
  117.         default:
  118.             TIFFError(TIFFFileName(tif),
  119.                 "Missing needed \"PhotometricInterpretation\" tag");
  120.             return (0);
  121.         }
  122.         TIFFError(TIFFFileName(tif),
  123.             "No \"PhotometricInterpretation\" tag, assuming %s\n",
  124.             photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
  125.     }
  126.     switch (photometric) {
  127.     case PHOTOMETRIC_MINISWHITE:
  128.     case PHOTOMETRIC_MINISBLACK:
  129.     case PHOTOMETRIC_RGB:
  130.     case PHOTOMETRIC_PALETTE:
  131.     case PHOTOMETRIC_YCBCR:
  132.         break;
  133.     case PHOTOMETRIC_SEPARATED: {
  134.         uint16 inkset;
  135.         TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
  136.         if (inkset != INKSET_CMYK) {
  137.             TIFFError(TIFFFileName(tif),
  138.                 "Sorry, can not handle separated image with %s=%d",
  139.                 "InkSet", inkset);
  140.             return (0);
  141.         }
  142.         break;
  143.     }
  144.     default:
  145.         TIFFError(TIFFFileName(tif),
  146.             "Sorry, can not handle image with %s=%d",
  147.             "PhotometricInterpretation", photometric);
  148.         return (0);
  149.     }
  150.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  151.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  152.     /* XXX verify rwidth and rheight against width and height */
  153.     stoponerr = stop;
  154.     BWmap = NULL;
  155.     PALmap = NULL;
  156.     ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
  157.     if (BWmap)
  158.         _TIFFfree((char *)BWmap);
  159.     if (PALmap)
  160.         _TIFFfree((char *)PALmap);
  161.     return (ok);
  162. }
  163.  
  164. static int
  165. checkcmap(long n, uint16* r, uint16* g, uint16* b)
  166. {
  167.     while (n-- > 0)
  168.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  169.             return (16);
  170.     return (8);
  171. }
  172.  
  173. /*
  174.  * Construct a mapping table to convert from the range
  175.  * of the data samples to [0,255] --for display.  This
  176.  * process also handles inverting B&W images when needed.
  177.  */ 
  178. static int
  179. setupMap(TIFF* tif,
  180.     uint16 minsamplevalue, uint16 maxsamplevalue, RGBvalue** pMap)
  181. {
  182.     register int x, range;
  183.     RGBvalue *Map;
  184.  
  185.     range = maxsamplevalue - minsamplevalue;
  186.     Map = (RGBvalue *)_TIFFmalloc((range + 1) * sizeof (RGBvalue));
  187.     if (Map == NULL) {
  188.         TIFFError(TIFFFileName(tif),
  189.             "No space for photometric conversion table");
  190.         return (0);
  191.     }
  192.     if (photometric == PHOTOMETRIC_MINISWHITE) {
  193.         for (x = 0; x <= range; x++)
  194.             Map[x] = ((range - x) * 255) / range;
  195.     } else {
  196.         for (x = 0; x <= range; x++)
  197.             Map[x] = (x * 255) / range;
  198.     }
  199.     if (bitspersample <= 8 &&
  200.         (photometric == PHOTOMETRIC_MINISBLACK ||
  201.          photometric == PHOTOMETRIC_MINISWHITE)) {
  202.         /*
  203.          * Use photometric mapping table to construct
  204.          * unpacking tables for samples <= 8 bits.
  205.          */
  206.         if (!makebwmap(tif, Map))
  207.             return (0);
  208.         /* no longer need Map, free it */
  209.         _TIFFfree((char *)Map);
  210.         Map = NULL;
  211.     }
  212.     *pMap = Map;
  213.     return (1);
  214. }
  215.  
  216. static int
  217. gt(TIFF* tif, uint32 w, uint32 h, uint32* raster)
  218. {
  219.     uint16 minsamplevalue, maxsamplevalue;
  220.     RGBvalue *Map;
  221.     int e, ncomps;
  222.  
  223.     TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
  224.     TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
  225.     Map = NULL;
  226.     switch (photometric) {
  227.     case PHOTOMETRIC_YCBCR:
  228.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
  229.             &YCbCrCoeffs);
  230.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
  231.             &YCbCrHorizSampling, &YCbCrVertSampling);
  232.         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
  233.             &refBlackWhite);
  234.         initYCbCrConversion();
  235.         /* fall thru... */
  236.     case PHOTOMETRIC_RGB:
  237.     case PHOTOMETRIC_SEPARATED:
  238.         if (minsamplevalue == 0 && maxsamplevalue == 255)
  239.             break;
  240.         /* fall thru... */
  241.     case PHOTOMETRIC_MINISBLACK:
  242.     case PHOTOMETRIC_MINISWHITE:
  243.         if (!setupMap(tif, minsamplevalue, maxsamplevalue, &Map))
  244.             return (0);
  245.         break;
  246.     case PHOTOMETRIC_PALETTE:
  247.         if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  248.                   &redcmap, &greencmap, &bluecmap)) {
  249.             TIFFError(TIFFFileName(tif),
  250.                 "Missing required \"Colormap\" tag");
  251.             return (0);
  252.         }
  253.         /*
  254.          * Convert 16-bit colormap to 8-bit (unless it looks
  255.          * like an old-style 8-bit colormap).
  256.          */
  257.         if (checkcmap(1L<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
  258.             long i;
  259.             for (i = (1L<<bitspersample)-1; i > 0; i--) {
  260. #define    CVT(x)        ((uint16)(((x) * 255) / ((1L<<16)-1)))
  261.                 redcmap[i] = CVT(redcmap[i]);
  262.                 greencmap[i] = CVT(greencmap[i]);
  263.                 bluecmap[i] = CVT(bluecmap[i]);
  264.             }
  265.         } else
  266.             TIFFWarning(TIFFFileName(tif), "Assuming 8-bit colormap");
  267.         if (bitspersample <= 8) {
  268.             /*
  269.              * Use mapping table and colormap to construct
  270.              * unpacking tables for samples < 8 bits.
  271.              */
  272.             if (!makecmap(tif, redcmap, greencmap, bluecmap))
  273.                 return (0);
  274.         }
  275.         break;
  276.     }
  277.     ncomps = samplesperpixel - extrasamples;
  278.     if (planarconfig == PLANARCONFIG_SEPARATE && ncomps > 1) {
  279.         e = TIFFIsTiled(tif) ?
  280.             gtTileSeparate(tif, raster, Map, h, w) :
  281.             gtStripSeparate(tif, raster, Map, h, w);
  282.     } else {
  283.         e = TIFFIsTiled(tif) ? 
  284.             gtTileContig(tif, raster, Map, h, w) :
  285.             gtStripContig(tif, raster, Map, h, w);
  286.     }
  287.     if (Map)
  288.         _TIFFfree((char *)Map);
  289.     return (e);
  290. }
  291.  
  292. static uint32
  293. setorientation(TIFF* tif, uint32 h)
  294. {
  295.     uint32 y;
  296.  
  297.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
  298.     switch (orientation) {
  299.     case ORIENTATION_BOTRIGHT:
  300.     case ORIENTATION_RIGHTBOT:    /* XXX */
  301.     case ORIENTATION_LEFTBOT:    /* XXX */
  302.         TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
  303.         orientation = ORIENTATION_BOTLEFT;
  304.         /* fall thru... */
  305.     case ORIENTATION_BOTLEFT:
  306.         y = 0;
  307.         break;
  308.     case ORIENTATION_TOPRIGHT:
  309.     case ORIENTATION_RIGHTTOP:    /* XXX */
  310.     case ORIENTATION_LEFTTOP:    /* XXX */
  311.     default:
  312.         TIFFWarning(TIFFFileName(tif), "using top-left orientation");
  313.         orientation = ORIENTATION_TOPLEFT;
  314.         /* fall thru... */
  315.     case ORIENTATION_TOPLEFT:
  316.         y = h-1;
  317.         break;
  318.     }
  319.     return (y);
  320. }
  321.  
  322. typedef void (*tileContigRoutine)
  323.     (uint32*, u_char*, RGBvalue*, uint32, uint32, int, int);
  324. static tileContigRoutine pickTileContigCase(TIFF*, RGBvalue*);
  325.  
  326. /*
  327.  * Get an tile-organized image that has
  328.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  329.  * or
  330.  *    SamplesPerPixel == 1
  331.  */    
  332. static int
  333. gtTileContig(TIFF* tif, uint32* raster, RGBvalue* Map, uint32 h, uint32 w)
  334. {
  335.     uint32 col, row, y;
  336.     uint32 tw, th;
  337.     u_char *buf;
  338.     int32 fromskew, toskew;
  339.     uint32 nrow;
  340.     tileContigRoutine put;
  341.  
  342.     put = pickTileContigCase(tif, Map);
  343.     if (put == 0)
  344.         return (0);
  345.     buf = (u_char *)_TIFFmalloc(TIFFTileSize(tif));
  346.     if (buf == 0) {
  347.         TIFFError(TIFFFileName(tif), "No space for tile buffer");
  348.         return (0);
  349.     }
  350.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  351.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  352.     y = setorientation(tif, h);
  353.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  354.     for (row = 0; row < h; row += th) {
  355.         nrow = (row + th > h ? h - row : th);
  356.         for (col = 0; col < w; col += tw) {
  357.             if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
  358.                 stoponerr)
  359.                 break;
  360.             if (col + tw > w) {
  361.                 /*
  362.                  * Tile is clipped horizontally.  Calculate
  363.                  * visible portion and skewing factors.
  364.                  */
  365.                 uint32 npix = w - col;
  366.                 fromskew = tw - npix;
  367.                 (*put)(raster + y*w + col, buf, Map,
  368.                     npix, nrow, fromskew, toskew + fromskew);
  369.             } else
  370.                 (*put)(raster + y*w + col, buf, Map,
  371.                     tw, nrow, 0, toskew);
  372.         }
  373.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  374.     }
  375.     _TIFFfree(buf);
  376.     return (1);
  377. }
  378.  
  379. typedef void (*tileSeparateRoutine)
  380.     (uint32*, u_char*, u_char*, u_char*, RGBvalue*, uint32, uint32, int, int);
  381. static tileSeparateRoutine pickTileSeparateCase(TIFF*, RGBvalue*);
  382.  
  383. /*
  384.  * Get an tile-organized image that has
  385.  *     SamplesPerPixel > 1
  386.  *     PlanarConfiguration separated
  387.  * We assume that all such images are RGB.
  388.  */    
  389. static int
  390. gtTileSeparate(TIFF* tif, uint32* raster, RGBvalue* Map, uint32 h, uint32 w)
  391. {
  392.     uint32 col, row, y;
  393.     uint32 tw, th;
  394.     u_char *buf;
  395.     u_char *r, *g, *b;
  396.     tsize_t tilesize;
  397.     int32 fromskew, toskew;
  398.     uint32 nrow;
  399.     tileSeparateRoutine put;
  400.  
  401.     put = pickTileSeparateCase(tif, Map);
  402.     if (put == 0)
  403.         return (0);
  404.     tilesize = TIFFTileSize(tif);
  405.     buf = (u_char *)_TIFFmalloc(3*tilesize);
  406.     if (buf == 0) {
  407.         TIFFError(TIFFFileName(tif), "No space for tile buffer");
  408.         return (0);
  409.     }
  410.     r = buf;
  411.     g = r + tilesize;
  412.     b = g + tilesize;
  413.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  414.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  415.     y = setorientation(tif, h);
  416.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  417.     for (row = 0; row < h; row += th) {
  418.         nrow = (row + th > h ? h - row : th);
  419.         for (col = 0; col < w; col += tw) {
  420.             if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
  421.                 break;
  422.             if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
  423.                 break;
  424.             if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
  425.                 break;
  426.             if (col + tw > w) {
  427.                 /*
  428.                  * Tile is clipped horizontally.  Calculate
  429.                  * visible portion and skewing factors.
  430.                  */
  431.                 uint32 npix = w - col;
  432.                 fromskew = tw - npix;
  433.                 (*put)(raster + y*w + col, r, g, b, Map,
  434.                     npix, nrow, fromskew, toskew + fromskew);
  435.             } else
  436.                 (*put)(raster + y*w + col, r, g, b, Map,
  437.                     tw, nrow, 0, toskew);
  438.         }
  439.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  440.     }
  441.     _TIFFfree(buf);
  442.     return (1);
  443. }
  444.  
  445. /*
  446.  * Get a strip-organized image that has
  447.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  448.  * or
  449.  *    SamplesPerPixel == 1
  450.  */    
  451. static int
  452. gtStripContig(TIFF* tif, uint32* raster, RGBvalue* Map, uint32 h, uint32 w)
  453. {
  454.     uint32 row, y, nrow;
  455.     u_char *buf;
  456.     tileContigRoutine put;
  457.     uint32 rowsperstrip;
  458.     uint32 imagewidth;
  459.     tsize_t scanline;
  460.     int fromskew, toskew;
  461.  
  462.     put = pickTileContigCase(tif, Map);
  463.     if (put == 0)
  464.         return (0);
  465.     buf = (u_char *)_TIFFmalloc(TIFFStripSize(tif));
  466.     if (buf == 0) {
  467.         TIFFError(TIFFFileName(tif), "No space for strip buffer");
  468.         return (0);
  469.     }
  470.     y = setorientation(tif, h);
  471.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  472.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  473.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  474.     scanline = TIFFScanlineSize(tif);
  475.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  476.     for (row = 0; row < h; row += rowsperstrip) {
  477.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  478.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  479.             buf, nrow*scanline) < 0 && stoponerr)
  480.             break;
  481.         (*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
  482.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  483.     }
  484.     _TIFFfree(buf);
  485.     return (1);
  486. }
  487.  
  488. /*
  489.  * Get a strip-organized image with
  490.  *     SamplesPerPixel > 1
  491.  *     PlanarConfiguration separated
  492.  * We assume that all such images are RGB.
  493.  */
  494. static int
  495. gtStripSeparate(TIFF* tif, uint32* raster, RGBvalue* Map, uint32 h, uint32 w)
  496. {
  497.     u_char *buf;
  498.     u_char *r, *g, *b;
  499.     uint32 row, y, nrow;
  500.     tsize_t scanline;
  501.     tileSeparateRoutine put;
  502.     uint32 rowsperstrip;
  503.     uint32 imagewidth;
  504.     tsize_t stripsize;
  505.     int fromskew, toskew;
  506.  
  507.     stripsize = TIFFStripSize(tif);
  508.     r = buf = (u_char *)_TIFFmalloc(3*stripsize);
  509.     if (buf == 0)
  510.         return (0);
  511.     g = r + stripsize;
  512.     b = g + stripsize;
  513.     put = pickTileSeparateCase(tif, Map);
  514.     if (put == 0) {
  515.         TIFFError(TIFFFileName(tif), "Can not handle format");
  516.         return (0);
  517.     }
  518.     y = setorientation(tif, h);
  519.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  520.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  521.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  522.     scanline = TIFFScanlineSize(tif);
  523.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  524.     for (row = 0; row < h; row += rowsperstrip) {
  525.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  526.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  527.             r, nrow*scanline) < 0 && stoponerr)
  528.             break;
  529.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
  530.             g, nrow*scanline) < 0 && stoponerr)
  531.             break;
  532.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
  533.             b, nrow*scanline) < 0 && stoponerr)
  534.             break;
  535.         (*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
  536.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  537.     }
  538.     _TIFFfree(buf);
  539.     return (1);
  540. }
  541.  
  542. #define    PACK(r,g,b)    ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16))
  543.  
  544. /*
  545.  * Greyscale images with less than 8 bits/sample are handled
  546.  * with a table to avoid lots of shifts and masks.  The table
  547.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  548.  * pixel values simply by indexing into the table with one
  549.  * number.
  550.  */
  551. static int
  552. makebwmap(TIFF* tif, RGBvalue* Map)
  553. {
  554.     register int i;
  555.     int nsamples = 8 / bitspersample;
  556.     register uint32 *p;
  557.  
  558.     BWmap = (uint32 **)_TIFFmalloc(
  559.         256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
  560.     if (BWmap == NULL) {
  561.         TIFFError(TIFFFileName(tif), "No space for B&W mapping table");
  562.         return (0);
  563.     }
  564.     p = (uint32 *)(BWmap + 256);
  565.     for (i = 0; i < 256; i++) {
  566.         BWmap[i] = p;
  567.         switch (bitspersample) {
  568.             register RGBvalue c;
  569. #define    GREY(x)    c = Map[x]; *p++ = PACK(c,c,c);
  570.         case 1:
  571.             GREY(i>>7);
  572.             GREY((i>>6)&1);
  573.             GREY((i>>5)&1);
  574.             GREY((i>>4)&1);
  575.             GREY((i>>3)&1);
  576.             GREY((i>>2)&1);
  577.             GREY((i>>1)&1);
  578.             GREY(i&1);
  579.             break;
  580.         case 2:
  581.             GREY(i>>6);
  582.             GREY((i>>4)&3);
  583.             GREY((i>>2)&3);
  584.             GREY(i&3);
  585.             break;
  586.         case 4:
  587.             GREY(i>>4);
  588.             GREY(i&0xf);
  589.             break;
  590.         case 8:
  591.             GREY(i);
  592.             break;
  593.         }
  594. #undef    GREY
  595.     }
  596.     return (1);
  597. }
  598.  
  599. /*
  600.  * Palette images with <= 8 bits/sample are handled
  601.  * with a table to avoid lots of shifts and masks.  The table
  602.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  603.  * pixel values simply by indexing into the table with one
  604.  * number.
  605.  */
  606. static int
  607. makecmap(TIFF* tif, uint16* rmap, uint16* gmap, uint16* bmap)
  608. {
  609.     register int i;
  610.     int nsamples = 8 / bitspersample;
  611.     register uint32 *p;
  612.  
  613.     PALmap = (uint32 **)_TIFFmalloc(
  614.         256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
  615.     if (PALmap == NULL) {
  616.         TIFFError(TIFFFileName(tif), "No space for Palette mapping table");
  617.         return (0);
  618.     }
  619.     p = (uint32 *)(PALmap + 256);
  620.     for (i = 0; i < 256; i++) {
  621.         PALmap[i] = p;
  622. #define    CMAP(x)    \
  623. c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
  624.         switch (bitspersample) {
  625.             register RGBvalue c;
  626.         case 1:
  627.             CMAP(i>>7);
  628.             CMAP((i>>6)&1);
  629.             CMAP((i>>5)&1);
  630.             CMAP((i>>4)&1);
  631.             CMAP((i>>3)&1);
  632.             CMAP((i>>2)&1);
  633.             CMAP((i>>1)&1);
  634.             CMAP(i&1);
  635.             break;
  636.         case 2:
  637.             CMAP(i>>6);
  638.             CMAP((i>>4)&3);
  639.             CMAP((i>>2)&3);
  640.             CMAP(i&3);
  641.             break;
  642.         case 4:
  643.             CMAP(i>>4);
  644.             CMAP(i&0xf);
  645.             break;
  646.         case 8:
  647.             CMAP(i);
  648.             break;
  649.         }
  650. #undef CMAP
  651.     }
  652.     return (1);
  653. }
  654.  
  655. /*
  656.  * The following routines move decoded data returned
  657.  * from the TIFF library into rasters filled with packed
  658.  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
  659.  *
  660.  * The routines have been created according to the most
  661.  * important cases and optimized.  pickTileContigCase and
  662.  * pickTileSeparateCase analyze the parameters and select
  663.  * the appropriate "put" routine to use.
  664.  */
  665. #define    REPEAT8(op)    REPEAT4(op); REPEAT4(op)
  666. #define    REPEAT4(op)    REPEAT2(op); REPEAT2(op)
  667. #define    REPEAT2(op)    op; op
  668. #define    CASE8(x,op)                \
  669.     switch (x) {                \
  670.     case 7: op; case 6: op; case 5: op;    \
  671.     case 4: op; case 3: op; case 2: op;    \
  672.     case 1: op;                \
  673.     }
  674. #define    CASE4(x,op)    switch (x) { case 3: op; case 2: op; case 1: op; }
  675. #define    NOP
  676.  
  677. #define    UNROLL8(w, op1, op2) {        \
  678.     register uint32 x;        \
  679.     for (x = w; x >= 8; x -= 8) {    \
  680.         op1;            \
  681.         REPEAT8(op2);        \
  682.     }                \
  683.     if (x > 0) {            \
  684.         op1;            \
  685.         CASE8(x,op2);        \
  686.     }                \
  687. }
  688. #define    UNROLL4(w, op1, op2) {        \
  689.     register uint32 x;        \
  690.     for (x = w; x >= 4; x -= 4) {    \
  691.         op1;            \
  692.         REPEAT4(op2);        \
  693.     }                \
  694.     if (x > 0) {            \
  695.         op1;            \
  696.         CASE4(x,op2);        \
  697.     }                \
  698. }
  699. #define    UNROLL2(w, op1, op2) {        \
  700.     register uint32 x;        \
  701.     for (x = w; x >= 2; x -= 2) {    \
  702.         op1;            \
  703.         REPEAT2(op2);        \
  704.     }                \
  705.     if (x) {            \
  706.         op1;            \
  707.         op2;            \
  708.     }                \
  709. }
  710.             
  711.  
  712. #define    SKEW(r,g,b,skew)    { r += skew; g += skew; b += skew; }
  713.  
  714. #define    DECLAREContigPutFunc(name) \
  715. static void name(\
  716.     uint32* cp, \
  717.     u_char* pp, \
  718.     RGBvalue* Map, \
  719.     uint32 w, uint32 h, \
  720.     int fromskew, int toskew \
  721. )
  722.  
  723. /*
  724.  * 8-bit palette => colormap/RGB
  725.  */
  726. DECLAREContigPutFunc(put8bitcmaptile)
  727. {
  728.     while (h-- > 0) {
  729.         UNROLL8(w, NOP, *cp++ = PALmap[*pp++][0]);
  730.         cp += toskew;
  731.         pp += fromskew;
  732.     }
  733. }
  734.  
  735. /*
  736.  * 4-bit palette => colormap/RGB
  737.  */
  738. DECLAREContigPutFunc(put4bitcmaptile)
  739. {
  740.     register uint32 *bw;
  741.  
  742.     fromskew /= 2;
  743.     while (h-- > 0) {
  744.         UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  745.         cp += toskew;
  746.         pp += fromskew;
  747.     }
  748. }
  749.  
  750. /*
  751.  * 2-bit palette => colormap/RGB
  752.  */
  753. DECLAREContigPutFunc(put2bitcmaptile)
  754. {
  755.     register uint32 *bw;
  756.  
  757.     fromskew /= 4;
  758.     while (h-- > 0) {
  759.         UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  760.         cp += toskew;
  761.         pp += fromskew;
  762.     }
  763. }
  764.  
  765. /*
  766.  * 1-bit palette => colormap/RGB
  767.  */
  768. DECLAREContigPutFunc(put1bitcmaptile)
  769. {
  770.     register uint32 *bw;
  771.  
  772.     fromskew /= 8;
  773.     while (h-- > 0) {
  774.         UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  775.         cp += toskew;
  776.         pp += fromskew;
  777.     }
  778. }
  779.  
  780. /*
  781.  * 8-bit greyscale => colormap/RGB
  782.  */
  783. DECLAREContigPutFunc(putgreytile)
  784. {
  785.     while (h-- > 0) {
  786.         register uint32 x;
  787.         for (x = w; x-- > 0;)
  788.             *cp++ = BWmap[*pp++][0];
  789.         cp += toskew;
  790.         pp += fromskew;
  791.     }
  792. }
  793.  
  794. /*
  795.  * 1-bit bilevel => colormap/RGB
  796.  */
  797. DECLAREContigPutFunc(put1bitbwtile)
  798. {
  799.     register uint32 *bw;
  800.  
  801.     fromskew /= 8;
  802.     while (h-- > 0) {
  803.         UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  804.         cp += toskew;
  805.         pp += fromskew;
  806.     }
  807. }
  808.  
  809. /*
  810.  * 2-bit greyscale => colormap/RGB
  811.  */
  812. DECLAREContigPutFunc(put2bitbwtile)
  813. {
  814.     register uint32 *bw;
  815.  
  816.     fromskew /= 4;
  817.     while (h-- > 0) {
  818.         UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  819.         cp += toskew;
  820.         pp += fromskew;
  821.     }
  822. }
  823.  
  824. /*
  825.  * 4-bit greyscale => colormap/RGB
  826.  */
  827. DECLAREContigPutFunc(put4bitbwtile)
  828. {
  829.     register uint32 *bw;
  830.  
  831.     fromskew /= 2;
  832.     while (h-- > 0) {
  833.         UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  834.         cp += toskew;
  835.         pp += fromskew;
  836.     }
  837. }
  838.  
  839. /*
  840.  * 8-bit packed samples => RGB
  841.  */
  842. DECLAREContigPutFunc(putRGBcontig8bittile)
  843. {
  844.     fromskew *= samplesperpixel;
  845.     if (Map) {
  846.         while (h-- > 0) {
  847.             register uint32 x;
  848.             for (x = w; x-- > 0;) {
  849.                 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  850.                 pp += samplesperpixel;
  851.             }
  852.             pp += fromskew;
  853.             cp += toskew;
  854.         }
  855.     } else {
  856.         while (h-- > 0) {
  857.             UNROLL8(w, NOP,
  858.                 *cp++ = PACK(pp[0], pp[1], pp[2]);
  859.                 pp += samplesperpixel);
  860.             cp += toskew;
  861.             pp += fromskew;
  862.         }
  863.     }
  864. }
  865.  
  866. /*
  867.  * 16-bit packed samples => RGB
  868.  */
  869. DECLAREContigPutFunc(putRGBcontig16bittile)
  870. {
  871.     register u_short *wp = (u_short *)pp;
  872.     register uint32 x;
  873.  
  874.     fromskew *= samplesperpixel;
  875.     if (Map) {
  876.         while (h-- > 0) {
  877.             for (x = w; x-- > 0;) {
  878.                 *cp++ = PACK(Map[wp[0]], Map[wp[1]], Map[wp[2]]);
  879.                 wp += samplesperpixel;
  880.             }
  881.             cp += toskew;
  882.             wp += fromskew;
  883.         }
  884.     } else {
  885.         while (h-- > 0) {
  886.             for (x = w; x-- > 0;) {
  887.                 *cp++ = PACK(wp[0], wp[1], wp[2]);
  888.                 wp += samplesperpixel;
  889.             }
  890.             cp += toskew;
  891.             wp += fromskew;
  892.         }
  893.     }
  894. }
  895.  
  896. /*
  897.  * 8-bit packed CMYK samples => RGB
  898.  *
  899.  * NB: The conversion of CMYK->RGB is *very* crude.
  900.  */
  901. DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
  902. {
  903.     u_short r, g, b, k;
  904.  
  905.     fromskew *= samplesperpixel;
  906.     if (Map) {
  907.         while (h-- > 0) {
  908.             register uint32 x;
  909.             for (x = w; x-- > 0;) {
  910.                 k = 255 - pp[3];
  911.                 r = (k*(255-pp[0]))/255;
  912.                 g = (k*(255-pp[1]))/255;
  913.                 b = (k*(255-pp[2]))/255;
  914.                 *cp++ = PACK(Map[r], Map[g], Map[b]);
  915.                 pp += samplesperpixel;
  916.             }
  917.             pp += fromskew;
  918.             cp += toskew;
  919.         }
  920.     } else {
  921.         while (h-- > 0) {
  922.             UNROLL8(w, NOP,
  923.                 k = 255 - pp[3];
  924.                 r = (k*(255-pp[0]))/255;
  925.                 g = (k*(255-pp[1]))/255;
  926.                 b = (k*(255-pp[2]))/255;
  927.                 *cp++ = PACK(r, g, b);
  928.                 pp += samplesperpixel);
  929.             cp += toskew;
  930.             pp += fromskew;
  931.         }
  932.     }
  933. }
  934.  
  935. #define    DECLARESepPutFunc(name) \
  936. static void name(\
  937.     uint32* cp, \
  938.     u_char* r, u_char* g, u_char* b, \
  939.     RGBvalue* Map, \
  940.     uint32 w, uint32 h, \
  941.     int fromskew, int toskew \
  942. )
  943.  
  944. /*
  945.  * 8-bit unpacked samples => RGB
  946.  */
  947. DECLARESepPutFunc(putRGBseparate8bittile)
  948. {
  949.     if (Map) {
  950.         while (h-- > 0) {
  951.             register uint32 x;
  952.             for (x = w; x > 0; x--)
  953.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  954.             SKEW(r, g, b, fromskew);
  955.             cp += toskew;
  956.         }
  957.     } else {
  958.         while (h-- > 0) {
  959.             UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
  960.             SKEW(r, g, b, fromskew);
  961.             cp += toskew;
  962.         }
  963.     }
  964. }
  965.  
  966. /*
  967.  * 16-bit unpacked samples => RGB
  968.  */
  969. DECLARESepPutFunc(putRGBseparate16bittile)
  970. {
  971.     register u_short *wr = (u_short *)r;
  972.     register u_short *wg = (u_short *)g;
  973.     register u_short *wb = (u_short *)b;
  974.     register uint32 x;
  975.  
  976.     if (Map) {
  977.         while (h-- > 0) {
  978.             for (x = w; x > 0; x--)
  979.                 *cp++ = PACK(Map[*wr++],Map[*wg++],Map[*wb++]);
  980.             SKEW(wr, wg, wb, fromskew);
  981.             cp += toskew;
  982.         }
  983.     } else {
  984.         while (h-- > 0) {
  985.             for (x = 0; x < w; x++)
  986.                 *cp++ = PACK(*wr++, *wg++, *wb++);
  987.             SKEW(wr, wg, wb, fromskew);
  988.             cp += toskew;
  989.         }
  990.     }
  991. }
  992.  
  993. #define    Code2V(c, RB, RW, CR)    ((((c)-RB)*(float)CR)/(float)(RW-RB))
  994. #define    CLAMP(f,min,max) \
  995.     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
  996.  
  997. #define    LumaRed        YCbCrCoeffs[0]
  998. #define    LumaGreen    YCbCrCoeffs[1]
  999. #define    LumaBlue    YCbCrCoeffs[2]
  1000.  
  1001. static    float D1, D2;
  1002. static    float D3, D4;
  1003.  
  1004. static void
  1005. initYCbCrConversion(void)
  1006. {
  1007.     D1 = 2 - 2*LumaRed;
  1008.     D2 = D1*LumaRed / LumaGreen;
  1009.     D3 = 2 - 2*LumaBlue;
  1010.     D4 = D3*LumaBlue / LumaGreen;
  1011. }
  1012.  
  1013. static void
  1014. putRGBContigYCbCrClump(
  1015.     register uint32* cp, register u_char* pp,
  1016.     int cw, int ch,
  1017.     uint32 w,
  1018.     int n, int fromskew, int toskew
  1019. )
  1020. {
  1021.     float Cb, Cr;
  1022.     int j, k;
  1023.  
  1024.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1025.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1026.     for (j = 0; j < ch; j++) {
  1027.         for (k = 0; k < cw; k++) {
  1028.             float Y, R, G, B;
  1029.             Y = Code2V(*pp++,
  1030.                 refBlackWhite[0], refBlackWhite[1], 255);
  1031.             R = Y + Cr*D1;
  1032.             B = Y + Cb*D3;
  1033.             G = Y - Cb*D4 - Cr*D2;
  1034.             cp[k] = PACK(CLAMP(R,0,255),
  1035.                      CLAMP(G,0,255),
  1036.                      CLAMP(B,0,255));
  1037.         }
  1038.         cp += w+toskew;
  1039.         pp += fromskew;
  1040.     }
  1041. }
  1042. #undef LumaBlue
  1043. #undef LumaGreen
  1044. #undef LumaRed
  1045. #undef CLAMP
  1046. #undef Code2V
  1047.  
  1048. /*
  1049.  * 8-bit packed YCbCr samples => RGB
  1050.  */
  1051. DECLAREContigPutFunc(putcontig8bitYCbCrtile)
  1052. {
  1053.     u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
  1054.     uint32 *tp;
  1055.     uint32 x;
  1056.  
  1057.     /* XXX adjust fromskew */
  1058.     while (h >= YCbCrVertSampling) {
  1059.         tp = cp;
  1060.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1061.             putRGBContigYCbCrClump(tp, pp,
  1062.                 YCbCrHorizSampling, YCbCrVertSampling,
  1063.                 w, Coff, 0, toskew);
  1064.             tp += YCbCrHorizSampling;
  1065.             pp += Coff+2;
  1066.         }
  1067.         if (x > 0) {
  1068.             putRGBContigYCbCrClump(tp, pp,
  1069.                 x, YCbCrVertSampling,
  1070.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1071.             pp += Coff+2;
  1072.         }
  1073.         cp += YCbCrVertSampling*(w + toskew);
  1074.         pp += fromskew;
  1075.         h -= YCbCrVertSampling;
  1076.     }
  1077.     if (h > 0) {
  1078.         tp = cp;
  1079.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1080.             putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
  1081.                 w, Coff, 0, toskew);
  1082.             tp += YCbCrHorizSampling;
  1083.             pp += Coff+2;
  1084.         }
  1085.         if (x > 0)
  1086.             putRGBContigYCbCrClump(tp, pp, x, h,
  1087.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1088.     }
  1089. }
  1090.  
  1091. /*
  1092.  * Select the appropriate conversion routine for packed data.
  1093.  */
  1094. static tileContigRoutine
  1095. pickTileContigCase(TIFF* tif, RGBvalue* Map)
  1096. {
  1097.     tileContigRoutine put = 0;
  1098.  
  1099.     switch (photometric) {
  1100.     case PHOTOMETRIC_RGB:
  1101.         if (bitspersample == 8)
  1102.             put = putRGBcontig8bittile;
  1103.         else
  1104.             put = putRGBcontig16bittile;
  1105.         break;
  1106.     case PHOTOMETRIC_SEPARATED:
  1107.         if (bitspersample == 8)
  1108.             put = putRGBcontig8bitCMYKtile;
  1109.         break;
  1110.     case PHOTOMETRIC_PALETTE:
  1111.         switch (bitspersample) {
  1112.         case 8:    put = put8bitcmaptile; break;
  1113.         case 4: put = put4bitcmaptile; break;
  1114.         case 2: put = put2bitcmaptile; break;
  1115.         case 1: put = put1bitcmaptile; break;
  1116.         }
  1117.         break;
  1118.     case PHOTOMETRIC_MINISWHITE:
  1119.     case PHOTOMETRIC_MINISBLACK:
  1120.         switch (bitspersample) {
  1121.         case 8:    put = putgreytile; break;
  1122.         case 4: put = put4bitbwtile; break;
  1123.         case 2: put = put2bitbwtile; break;
  1124.         case 1: put = put1bitbwtile; break;
  1125.         }
  1126.         break;
  1127.     case PHOTOMETRIC_YCBCR:
  1128.         switch (bitspersample) {
  1129.         case 8: put = putcontig8bitYCbCrtile; break;
  1130.         }
  1131.         break;
  1132.     }
  1133.     if (put == 0)
  1134.         TIFFError(TIFFFileName(tif), "Can not handle format");
  1135.     return (put);
  1136. }
  1137.  
  1138. /*
  1139.  * Select the appropriate conversion routine for unpacked data.
  1140.  *
  1141.  * NB: we assume that unpacked single channel data is directed
  1142.  *     to the "packed routines.
  1143.  */
  1144. static tileSeparateRoutine
  1145. pickTileSeparateCase(TIFF* tif, RGBvalue* Map)
  1146. {
  1147.     tileSeparateRoutine put = 0;
  1148.  
  1149.     switch (photometric) {
  1150.     case PHOTOMETRIC_RGB:
  1151.         if (bitspersample == 8)
  1152.             put = putRGBseparate8bittile;
  1153.         else
  1154.             put = putRGBseparate16bittile;
  1155.         break;
  1156.     }
  1157.     if (put == 0)
  1158.         TIFFError(TIFFFileName(tif), "Can not handle format");
  1159.     return (put);
  1160. }
  1161.